package com.daxue.lcm.api.grpc.config;

import com.daxue.lcm.api.grpc.client.AbstractGrpcServiceClient;
import io.grpc.Channel;
import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors;
import io.grpc.ManagedChannelBuilder;
import io.grpc.inprocess.InProcessChannelBuilder;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.util.StringUtils;

/**
 * @author daxue0929
 * @date 2022/9/28
 */

public abstract class AbstractGrpcServiceConfiguration<T extends AbstractGrpcServiceClient> {

    public AbstractGrpcServiceConfiguration() {
    }

    protected Channel genChannel(final String serviceName, final GrpcServiceInfo serviceInfo) {
//        AlertUtils.notNull(serviceName, () -> {
//            return new BeanInitializationException(AlertUtils.alertNull("service name"));
//        });
//        AlertUtils.notNull(serviceInfo, () -> {
//            return new BeanInitializationException(AlertUtils.alertNull("service info"));
//        });
        Object channelBuilder;
        if (!serviceInfo.isEnabled()) {
            channelBuilder = InProcessChannelBuilder.forName(serviceName);
        } else if (StringUtils.hasText(serviceInfo.getTarget())) {
            channelBuilder = ManagedChannelBuilder.forTarget(serviceInfo.getTarget());
        } else {
            if (!StringUtils.hasText(serviceInfo.getHost())) {
                throw new BeanInitializationException("Invalid grpc configuration");
            }

            channelBuilder = ManagedChannelBuilder.forAddress(serviceInfo.getHost(), serviceInfo.getPort());
        }

        if (serviceInfo.getChannel().isUsePlaintext()) {
            ((ManagedChannelBuilder)channelBuilder).usePlaintext();
        }

        return ClientInterceptors.intercept(((ManagedChannelBuilder)channelBuilder).build(),
            new ClientInterceptor[]{new GrpcClientInterceptor()}
        );
    }

    protected abstract T instantiate(final GrpcServiceInfo grpcServiceInfo);

}
